<?php
declare (strict_types = 1);

namespace app\api\controller;

use app\api\model\Menu as MenuModel;
use think\Request;
use think\response\Json;

/**
 * 菜单管理控制器
 * 处理菜单相关的接口
 */
class Menu
{
    /**
     * 获取菜单列表
     * 前端期望的响应格式：
     * {
     *   records: Menu[],
     *   current: number,
     *   size: number,
     *   total: number
     * }
     * @param Request $request
     * @return Json
     */
    public function index(Request $request): Json
    {
        try {
            // 获取分页参数
            $current = (int) $request->param('current', 1);
            $size = (int) $request->param('size', 10);
            
            // 获取查询条件
            $menuName = $request->param('menuName', '');
            $status = $request->param('status', '');
            
            // 构建查询
            $query = MenuModel::order('order', 'asc')->order('id', 'asc');
            
            // 添加查询条件
            if (!empty($menuName)) {
                $query->where('menu_name', 'like', "%{$menuName}%");
            }
            if (!empty($status)) {
                $query->where('status', $status);
            }
            
            // 执行分页查询
            $list = $query->paginate([
                'list_rows' => $size,
                'page' => $current,
            ]);
            
            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => [
                    'records' => $list->items(),
                    'current' => $current,
                    'size' => $size,
                    'total' => $list->total(),
                ]
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '获取菜单列表失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 获取菜单列表（树形结构）
     * 前端接口：/systemManage/getMenuList
     * @param Request $request
     * @return Json
     */
    public function getMenuList(Request $request): Json
    {
        try {
            // 获取所有菜单并构建树形结构
            $tree = MenuModel::buildMenuTree();
            
            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => [
                    'records' => $tree,
                    'current' => 1,
                    'size' => count($tree),
                    'total' => count($tree),
                ]
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '获取菜单列表失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 获取菜单列表V2（树形结构）- 兼容旧接口
     * 前端接口：/systemManage/getMenuList/v2
     * @param Request $request
     * @return Json
     */
    public function getMenuListV2(Request $request): Json
    {
        // 调用新接口
        return $this->getMenuList($request);
    }
    
    /**
     * 获取菜单树（用于下拉选择）
     * 前端接口：/systemManage/getMenuTree
     * @return Json
     */
    public function getMenuTree(): Json
    {
        try {
            $tree = MenuModel::getMenuTreeForSelect();
            
            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => $tree
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '获取菜单树失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 获取所有页面路由
     * 前端接口：/systemManage/getAllPages
     * @return Json
     */
    public function getAllPages(): Json
    {
        try {
            // 获取所有菜单类型为2（页面）的路由名称
            $pages = MenuModel::where('menu_type', '2')
                ->where('status', '1')
                ->column('route_name');
            
            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => array_values(array_unique($pages))
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '获取所有页面失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 添加菜单
     * @param Request $request
     * @return Json
     */
    public function save(Request $request): Json
    {
        try {
            // 获取请求数据
            $data = $request->post();
            
            // 验证必填字段
            if (empty($data['menu_name'])) {
                return json([
                    'code' => 400,
                    'msg' => '菜单名称不能为空',
                    'data' => null
                ], 400);
            }
            
            if (empty($data['route_name'])) {
                return json([
                    'code' => 400,
                    'msg' => '路由名称不能为空',
                    'data' => null
                ], 400);
            }
            
            // 检查菜单名称是否已存在
            if (MenuModel::isMenuNameExists($data['menu_name'])) {
                return json([
                    'code' => 400,
                    'msg' => '菜单名称已存在',
                    'data' => null
                ], 400);
            }
            
            // 检查路由名称是否已存在
            if (MenuModel::isRouteNameExists($data['route_name'])) {
                return json([
                    'code' => 400,
                    'msg' => '路由名称已存在',
                    'data' => null
                ], 400);
            }
            
            // 处理JSON字段
            if (isset($data['query']) && is_array($data['query'])) {
                $data['query_params'] = json_encode($data['query'], JSON_UNESCAPED_UNICODE);
                unset($data['query']);
            }
            
            if (isset($data['buttons']) && is_array($data['buttons'])) {
                $data['buttons'] = json_encode($data['buttons'], JSON_UNESCAPED_UNICODE);
            }
            
            // 处理布尔值字段
            $boolFields = ['keep_alive', 'constant', 'hide_in_menu', 'multi_tab'];
            foreach ($boolFields as $field) {
                if (isset($data[$field])) {
                    $data[$field] = $data[$field] ? 1 : 0;
                }
            }
            
            // 设置默认值
            $data['parent_id'] = $data['parent_id'] ?? 0;
            $data['status'] = $data['status'] ?? '1';
            $data['menu_type'] = $data['menu_type'] ?? '1';
            $data['icon_type'] = $data['icon_type'] ?? '1';
            $data['order'] = $data['order'] ?? 0;
            
            // 创建菜单
            $menu = MenuModel::create($data);
            
            return json([
                'code' => 0,
                'msg' => '添加成功',
                'data' => $menu
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '添加菜单失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 更新菜单
     * @param Request $request
     * @param int $id
     * @return Json
     */
    public function update(Request $request, int $id): Json
    {
        try {
            // 查找菜单
            $menu = MenuModel::find($id);
            
            if (!$menu) {
                return json([
                    'code' => 404,
                    'msg' => '菜单不存在',
                    'data' => null
                ], 404);
            }
            
            // 获取请求数据
            $data = $request->post();
            
            // 验证必填字段
            if (isset($data['menu_name']) && empty($data['menu_name'])) {
                return json([
                    'code' => 400,
                    'msg' => '菜单名称不能为空',
                    'data' => null
                ], 400);
            }
            
            if (isset($data['route_name']) && empty($data['route_name'])) {
                return json([
                    'code' => 400,
                    'msg' => '路由名称不能为空',
                    'data' => null
                ], 400);
            }
            
            // 检查菜单名称是否已存在
            if (isset($data['menu_name']) && MenuModel::isMenuNameExists($data['menu_name'], $id)) {
                return json([
                    'code' => 400,
                    'msg' => '菜单名称已存在',
                    'data' => null
                ], 400);
            }
            
            // 检查路由名称是否已存在
            if (isset($data['route_name']) && MenuModel::isRouteNameExists($data['route_name'], $id)) {
                return json([
                    'code' => 400,
                    'msg' => '路由名称已存在',
                    'data' => null
                ], 400);
            }
            
            // 不允许将父菜单设置为自己或自己的子菜单
            if (isset($data['parent_id']) && $data['parent_id'] > 0) {
                $childrenIds = MenuModel::getMenuAndChildrenIds($id);
                if (in_array($data['parent_id'], $childrenIds)) {
                    return json([
                        'code' => 400,
                        'msg' => '不能将父菜单设置为自己或自己的子菜单',
                        'data' => null
                    ], 400);
                }
            }
            
            // 处理JSON字段
            if (isset($data['query']) && is_array($data['query'])) {
                $data['query_params'] = json_encode($data['query'], JSON_UNESCAPED_UNICODE);
                unset($data['query']);
            }
            
            if (isset($data['buttons']) && is_array($data['buttons'])) {
                $data['buttons'] = json_encode($data['buttons'], JSON_UNESCAPED_UNICODE);
            }
            
            // 处理布尔值字段
            $boolFields = ['keep_alive', 'constant', 'hide_in_menu', 'multi_tab'];
            foreach ($boolFields as $field) {
                if (isset($data[$field])) {
                    $data[$field] = $data[$field] ? 1 : 0;
                }
            }
            
            // 更新菜单
            $menu->save($data);
            
            return json([
                'code' => 0,
                'msg' => '更新成功',
                'data' => $menu
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '更新菜单失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 删除菜单
     * @param int $id
     * @return Json
     */
    public function delete(int $id): Json
    {
        try {
            // 查找菜单
            $menu = MenuModel::find($id);
            
            if (!$menu) {
                return json([
                    'code' => 404,
                    'msg' => '菜单不存在',
                    'data' => null
                ], 404);
            }
            
            // 检查是否有子菜单
            $childrenCount = MenuModel::where('parent_id', $id)->count();
            if ($childrenCount > 0) {
                return json([
                    'code' => 400,
                    'msg' => '该菜单下有子菜单，不能删除',
                    'data' => null
                ], 400);
            }
            
            // 删除菜单
            $menu->delete();
            
            return json([
                'code' => 0,
                'msg' => '删除成功',
                'data' => null
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '删除菜单失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 批量删除菜单
     * @param Request $request
     * @return Json
     */
    public function batchDelete(Request $request): Json
    {
        try {
            $ids = $request->param('ids', []);
            
            if (empty($ids) || !is_array($ids)) {
                return json([
                    'code' => 400,
                    'msg' => '请选择要删除的菜单',
                    'data' => null
                ], 400);
            }
            
            // 检查是否有子菜单
            $childrenCount = MenuModel::whereIn('parent_id', $ids)->count();
            if ($childrenCount > 0) {
                return json([
                    'code' => 400,
                    'msg' => '所选菜单中包含有子菜单的项，不能删除',
                    'data' => null
                ], 400);
            }
            
            // 批量删除
            MenuModel::destroy($ids);
            
            return json([
                'code' => 0,
                'msg' => '删除成功',
                'data' => null
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '批量删除菜单失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 获取菜单详情
     * @param int $id
     * @return Json
     */
    public function read(int $id): Json
    {
        try {
            $menu = MenuModel::find($id);
            
            if (!$menu) {
                return json([
                    'code' => 404,
                    'msg' => '菜单不存在',
                    'data' => null
                ], 404);
            }
            
            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => $menu
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '获取菜单详情失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
}
